/*
 * Backoff.java
 *
 * Created on November 19, 2006, 5:43 PM
 *
 * From "Multiprocessor Synchronization and Concurrent Data Structures",
 * by Maurice Herlihy and Nir Shavit.
 *
 * This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
 * http://i.creativecommons.org/l/by-sa/3.0/us/88x31.png
 */

package utils;

import java.util.Random;

/**
 * Adaptive exponential backoff class. Encapsulates back-off code common to many
 * classes.
 * 
 * @author Maurice Herlihy
 * 
 *         XXX NOT THEADSAFE.
 */
public class Backoff {
    public static final int MIN_BACKOFF = 1;
    public static final int MAX_BACKOFF = 500;
    final int minDelay, maxDelay;
    int limit; // wait between limit and 2*limit
    final Random random; // add randomness to wait

    /**
     * Prepare to pause for random duration.
     * 
     * @param min smallest back-off
     * @param max largest back-off
     */
    public Backoff(int min, int max) {
        if (max < min) {
            throw new IllegalArgumentException("max must be greater than min");
        }
        minDelay = min;
        maxDelay = min;
        limit = minDelay;
        random = new Random();
    }

    /**
     * Backoff for random duration.
     * 
     * @throws java.lang.InterruptedException
     */
    public void backoff() throws InterruptedException {
        int delay = random.nextInt(limit);
        if (limit < maxDelay) { // double limit if less than max
            limit = limit << 1; // limit = 2 * limit
        }
//        for (int i = 0; i < delay ; i++) {
//            
//        }
        Thread.sleep(delay);
    }
    
    public void resetLimit() {
        limit = minDelay;
    }
}
